
#include <Arduino.h>
#include <EEPROM.h>
#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT
#include <Blinker.h>
#include "LedController.h"

// LED控制器
LedController ledController;

#pragma region 基础功能设置
///////////////////////////////////////////////////////
// 基础功能设置
///////////////////////////////////////////////////////
//设置开关
void set_Switch(const bool state)
{
    BLINKER_LOG("set switch: ", state);
    LedState ledState = ledController.getLedState();
    ledState.switch_state = state ? 1 : 0;
    ledController.setLedState(ledState);
}
//设置开关
void set_Mode(const uint8_t mode)
{
    BLINKER_LOG("set mode: ", mode);
    LedState ledState = ledController.getLedState();
    ledState.show_type = LedShowType(int8_t(mode));
    ledController.setLedState(ledState);
}
//设置颜色
void set_Color(const CRGB &color)
{
    BLINKER_LOG("set color: ", color.red, color.green, color.blue);
    LedState ledState = ledController.getLedState();
    ledState.red_data = color.red;
    ledState.green_data = color.green;
    ledState.blue_data = color.blue;
    ledController.setLedState(ledState);
}
//设置亮度
void set_Brightness(const uint8_t bright)
{
    BLINKER_LOG("set brightness: ", bright);
    // uint8_t bright_data = bright.toInt();
    LedState ledState = ledController.getLedState();
    ledState.bright_data = bright;
    ledController.setLedState(ledState);
}
//设置色温
// todo:FastLED采用枚举方式，需要做映射
// enum ColorTemperature
void set_Temperature()
{

    // FastLED.setTemperature(ColorTemperature.Tungsten100W);
}
//写当前状态到EEPROM
void writeLedStateData()
{
    LedState ledState = ledController.getLedState();
    EEPROM.begin(6); //准备操作前6字节的数据
    EEPROM.write(0, ledState.show_type);
    EEPROM.write(1, ledState.switch_state);
    EEPROM.write(2, ledState.red_data);
    EEPROM.write(3, ledState.green_data);
    EEPROM.write(4, ledState.blue_data);
    EEPROM.write(5, ledState.bright_data);
    EEPROM.commit();
    EEPROM.end();
}
//从EEPROM读取状态
LedState readLedStateData()
{
    LedState ledState;
    EEPROM.begin(6);
    ledState.show_type = LedShowType(int8_t(EEPROM.read(0)));
    ledState.switch_state = EEPROM.read(1);
    ledState.red_data = EEPROM.read(2);
    ledState.green_data = EEPROM.read(3);
    ledState.blue_data = EEPROM.read(4);
    ledState.bright_data = EEPROM.read(5);
    EEPROM.commit();
    EEPROM.end();
    return ledState;
}

#pragma endregion 基础功能设置

#pragma region APP按钮定义

BlinkerNumber BlinkerShow("num-bright");
BlinkerButton appBtnSwitch("btn-switch");
BlinkerButton appBtnMode("btn-mode");
BlinkerButton appBtnRed("btn-red");
BlinkerButton appBtnYellow("btn-yellow");
BlinkerButton appBtnBlue("btn-blue");
BlinkerButton appBtnGreen("btn-green");
BlinkerRGB appBtnRgb("select-rgb");
BlinkerButton appBtnBrightAdd("btn-bright-add");
BlinkerButton appBtnBrightSub("btn-bright-sub");

#pragma endregion APP按钮定义

#pragma region APP回调设置
///////////////////////////////////////////////////////
// app回调设置
///////////////////////////////////////////////////////

void appSendBack()
{
    LedState ledState = ledController.getLedState();

    Serial.print("switch_state");
    Serial.print(ledState.switch_state);
    Serial.print("show_type");
    Serial.println(ledState.show_type);

    appBtnRgb.print(ledState.red_data, ledState.green_data, ledState.blue_data, ledState.bright_data);
    appBtnSwitch.print((ledState.switch_state == 0) ? BLINKER_CMD_OFF : BLINKER_CMD_ON);
    String state = (ledState.switch_state == 0) ? "关闭" : "打开";
    state.concat(" | ");
    // state.concat("模式");
    // state.concat(ledState.show_type);
    switch (ledState.show_type)
    {
    case LedShowType::COMMON:
        state.concat("自定模式");
        break;
    case LedShowType::DAY:
        state.concat("日光模式");
        break;
    case LedShowType::NIGHT:
        state.concat("月光模式");
        break;
    case LedShowType::COLOR:
        state.concat("彩光模式");
        break;
    case LedShowType::ColorPalette:
        state.concat("ColorPalette");
        break;
    case LedShowType::ColorTemperature1:
        state.concat("ColorTemperature");
        break;
    case LedShowType::Cylon:
        state.concat("Cylon");
        break;
    default:
        state.concat("其它模式");
        break;
    }
    BlinkerShow.text(state);
    // BlinkerShow.print要放在BlinkerShow.text后面，
    // 不然text显示有问题，可能是sdk库的bug
    BlinkerShow.print(ledState.bright_data);
}

void appBtnRed_callback(const String &state)
{
    BLINKER_LOG("app set color: ", "Red");
    set_Mode(LedShowType::COMMON);
    set_Color(CRGB::Red);
    writeLedStateData();
    appSendBack();
}
void appBtnGreen_callback(const String &state)
{
    BLINKER_LOG("app set color: ", "Green");
    set_Mode(LedShowType::COMMON);
    set_Color(CRGB::Green);
    writeLedStateData();
    appSendBack();
}
void appBtnBlue_callback(const String &state)
{
    BLINKER_LOG("app set color: ", "Blue");
    set_Mode(LedShowType::COMMON);
    set_Color(CRGB::Blue);
    writeLedStateData();
    appSendBack();
}
void appBtnYellow_callback(const String &state)
{
    BLINKER_LOG("app set color: ", "Yellow");
    set_Mode(LedShowType::COMMON);
    set_Color(CRGB::Yellow);
    writeLedStateData();
    appSendBack();
}
//开关
void appBtnSwitch_callback(const String &state)
{
    BLINKER_LOG("app set switch: ", state);
    if (state == BLINKER_CMD_ON)
    {
        set_Switch(true);
    }
    else if (state == BLINKER_CMD_OFF)
    {
        set_Switch(false);
    }
    writeLedStateData();
    appSendBack();
}
//模式
void appBtnMode_callback(const String &state)
{
    BLINKER_LOG("app set model: ", state);
    LedState ledState = ledController.getLedState();
    int max = LedShowType::Max;
    int curr = ledState.show_type;
    curr++;
    if (curr >= max)
    {
        curr = 0;
    }
    set_Mode(curr);
    writeLedStateData();
    appSendBack();
}
//设置颜色亮度
void appBtnRgb_callback(uint8_t r_data, uint8_t g_data, uint8_t b_data, uint8_t bright_data)
{
    BLINKER_LOG("set color&bright: ", "red：", r_data, "green", g_data, "blue", b_data, "bright", bright_data);
    set_Mode(LedShowType::COMMON);
    set_Color(CRGB(r_data, g_data, b_data));
    set_Brightness(bright_data);
    writeLedStateData();
    appSendBack();
}
//增加亮度
void appBtnBrightAdd_callback(const String &state)
{
    uint8_t bright_data = ledController.getLedState().bright_data;
    if (bright_data > 255 - 25)
    {
        bright_data = 255;
    }
    else
    {
        bright_data += 25;
    }
    set_Brightness(bright_data);
    writeLedStateData();
    appSendBack();
}
//减小亮度
void appBtnBrightSub_callback(const String &state)
{
    uint8_t bright_data = ledController.getLedState().bright_data;
    if (bright_data < 25)
    {
        bright_data = 0;
    }
    else
    {
        bright_data -= 25;
    }
    set_Brightness(bright_data);
    writeLedStateData();
    appSendBack();
}
//回调
void dataRead(const String &data)
{
    BLINKER_LOG("Blinker readString: ", data);
}

#pragma endregion APP回调设置

#pragma region 小米回调设置
///////////////////////////////////////////////////////
// 小米回调设置
///////////////////////////////////////////////////////
//电源管理
void miotPowerState(const String &state)
{
    BLINKER_LOG("MIOT set power state: ", state);

    if (state == BLINKER_CMD_ON)
    {
        set_Switch(true);
        BlinkerMIOT.powerState("on");
        BlinkerMIOT.print();
    }
    else if (state == BLINKER_CMD_OFF)
    {
        set_Switch(false);
        BlinkerMIOT.powerState("off");
        BlinkerMIOT.print();
    }

    //状态同时回传给APP
    writeLedStateData();
    appSendBack();
}

//小米控制色温范围为1000-10000
//务必在回调函数中反馈该控制状态
void miotColoTemp(int32_t colorTemp)
{
    BLINKER_LOG("MIOT set colorTemperature: ", colorTemp);

    int colorT = colorTemp;

    BlinkerMIOT.colorTemp(colorTemp);
    BlinkerMIOT.print();
}
//小米查询
void miotQuery(int32_t queryCode)
{
    BLINKER_LOG("MIOT Query codes: ", queryCode);

    switch (queryCode)
    {
    case BLINKER_CMD_QUERY_PM25_NUMBER:
        BLINKER_LOG("MIOT Query PM25");
        BlinkerMIOT.pm25(20);
        BlinkerMIOT.print();
        break;
    case BLINKER_CMD_QUERY_HUMI_NUMBER:
        BLINKER_LOG("MIOT Query HUMI");
        BlinkerMIOT.humi(20);
        BlinkerMIOT.print();
        break;
    case BLINKER_CMD_QUERY_TEMP_NUMBER:
        BLINKER_LOG("MIOT Query TEMP");
        BlinkerMIOT.temp(20);
        BlinkerMIOT.print();
        break;
    // case BLINKER_CMD_QUERY_TIME_NUMBER :
    //     BLINKER_LOG("MIOT Query Time");
    //     BlinkerMIOT.time(millis());
    //     BlinkerMIOT.print();
    //     break;
    default:
        BlinkerMIOT.temp(20);
        BlinkerMIOT.humi(20);
        BlinkerMIOT.pm25(20);
        BlinkerMIOT.co2(20);
        BlinkerMIOT.print();
        break;
    }
}
//小米模式设设置
void miotMode(uint8_t mode)
{
    BLINKER_LOG("MIOT set mode: ", mode);
    switch (mode)
    {
    case BLINKER_CMD_MIOT_DAY:
        set_Mode(LedShowType::DAY);
        break;
    case BLINKER_CMD_MIOT_NIGHT:
        set_Mode(LedShowType::NIGHT);
        break;
    case BLINKER_CMD_MIOT_COLOR:
        set_Mode(LedShowType::COLOR);
        break;
    default:
        set_Mode(LedShowType::DAY);
        mode = BLINKER_CMD_MIOT_DAY;
        break;
    }

    BlinkerMIOT.mode(mode);
    BlinkerMIOT.print();

    //状态同时回传给APP
    writeLedStateData();
    appSendBack();
}
//颜色设置
void miotColor(int32_t color)
{
    BLINKER_LOG("MIOT set color: ", color);

    uint8_t colorR = color >> 16 & 0xFF;
    uint8_t colorG = color >> 8 & 0xFF;
    uint8_t colorB = color & 0xFF;

    BLINKER_LOG("colorR: ", colorR, ", colorG: ", colorG, ", colorB: ", colorB);

    set_Mode(LedShowType::COMMON);
    set_Color(CRGB(color));

    BlinkerMIOT.color(color);
    BlinkerMIOT.print();

    writeLedStateData();
    appSendBack();
}
//设置亮度，亮度范围为1-100
void miotBright(const String &strBright)
{
    BLINKER_LOG("MIOT set brightness: ", strBright);

    uint8_t bright = strBright.toInt();

    // FastLED的亮度范围是0-255，需要做映射
    uint8_t mapBright = map(bright, 1, 100, 0, 255);
    set_Brightness(mapBright);

    BlinkerMIOT.brightness(bright);
    BlinkerMIOT.print();

    writeLedStateData();
    appSendBack();
}

#pragma endregion 小米回调设置

//程序启动设置
void setup()
{
    Serial.begin(115200);

    BLINKER_DEBUG.stream(Serial);
    // BLINKER_DEBUG.debugAll();

    //可以考虑写到EEPROM
    char auth[] = BLINKER_AUTH;
    char ssid[] = BLINKER_WIFI_SSID;
    char pswd[] = BLINKER_WIFI_PSWD;

    // 初始化blinker
    Blinker.begin(auth, ssid, pswd);

    Blinker.attachData(dataRead);
    Blinker.attachSwitch(appBtnSwitch_callback);

    // app按钮功能
    appBtnSwitch.attach(appBtnSwitch_callback);
    appBtnMode.attach(appBtnMode_callback);
    appBtnRed.attach(appBtnRed_callback);
    appBtnBlue.attach(appBtnBlue_callback);
    appBtnGreen.attach(appBtnGreen_callback);
    appBtnYellow.attach(appBtnYellow_callback);
    appBtnRgb.attach(appBtnRgb_callback);
    appBtnBrightAdd.attach(appBtnBrightAdd_callback);
    appBtnBrightSub.attach(appBtnBrightSub_callback);

    //以下为对接小米小爱接口
    BlinkerMIOT.attachPowerState(miotPowerState);     //电源
    BlinkerMIOT.attachBrightness(miotBright);         //亮度
    BlinkerMIOT.attachColor(miotColor);               //颜色
    BlinkerMIOT.attachColorTemperature(miotColoTemp); //色温
    BlinkerMIOT.attachQuery(miotQuery);               //查询
    BlinkerMIOT.attachMode(miotMode);                 //模式

    ledController.Setup();

    //等待数据网络连接
    while (!Blinker.connect())
    {
        Serial.println("Wait for blinker connected...");
        delay(100);
    }
    //第一次加载从EEPROM读取数据
    //处理未初始化产生的数据
    LedState ledState = readLedStateData();
    if (ledState.switch_state == 1)
    {
        if (ledState.bright_data == 0)
            ledState.bright_data = 128;
        if (ledState.show_type > 10)
            ledState.show_type = LedShowType::COMMON;

        ledController.setLedState(ledState);
    }

    appSendBack();
}

//程序循环控制
void loop()
{
    Blinker.run();
    ledController.show();
}